package com.spark.sniffer.plugin.plugins.define.trace;

import java.util.Arrays;

import com.spark.sniffer.plugin.interceptor.InstanceMethodsInterceptPoint;
import com.spark.sniffer.plugin.interceptor.StaticMethodsInterceptPoint;
import com.spark.sniffer.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import com.spark.sniffer.plugin.match.ClassMatch;
import com.spark.sniffer.plugin.match.NameMatch;
import com.spark.sniffer.plugin.plugins.interceptor.JedisInterceptor;

import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;

public class JedisPlugin extends ClassInstanceMethodsEnhancePluginDefine {

    @Override
    protected ClassMatch enhanceClass() {
        return NameMatch.byName("redis.clients.jedis.Jedis");
    }

    @Override
    protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {new InstanceMethodsInterceptPoint() {
            @Override
            public ElementMatcher<MethodDescription> getMethodsMatcher() {
                return getIntersectionalMethodMacher();
            }

            @Override
            public Class<?> getMethodsInterceptor() {
                return JedisInterceptor.class;
            }

            @Override
            public boolean isOverrideArgs() {
                return false;
            }
        }};
    }

    private ElementMatcher.Junction<MethodDescription> getIntersectionalMethodMacher() {
        return ElementMatchers.anyOf(Arrays.asList("zcount", "sunionstore", "zunionstore", "del", "zinterstore", "echo",
            "hscan", "psubscribe", "type", "sinterstore", "setex", "zlexcount", "brpoplpush", "bitcount", "llen",
            "zscan", "lpushx", "bitpos", "setnx", "hvals", "evalsha", "substr", "geodist", "zrangeByLex", "geoadd",
            "expire", "bitop", "zrangeByScore", "smove", "lset", "decrBy", "pttl", "scan", "zrank", "blpop",
            "rpoplpush", "zremrangeByLex", "get", "lpop", "persist", "scriptExists", "georadius", "set", "srandmember",
            "incr", "setbit", "hexists", "expireAt", "pexpire", "zcard", "bitfield", "zrevrangeByLex", "sinter", "srem",
            "getrange", "rename", "zrevrank", "exists", "setrange", "zremrangeByRank", "sadd", "sdiff", "zrevrange",
            "getbit", "scard", "sdiffstore", "zrevrangeByScore", "zincrby", "rpushx", "psetex", "zrevrangeWithScores",
            "strlen", "hdel", "zremrangeByScore", "geohash", "brpop", "lrem", "hlen", "decr", "scriptLoad", "lpush",
            "lindex", "zrange", "incrBy", "getSet", "ltrim", "incrByFloat", "rpop", "sort",
            "zrevrangeByScoreWithScores", "pfadd", "eval", "linsert", "pfcount", "hkeys", "hsetnx", "hincrBy",
            "hgetAll", "hset", "spop", "zrangeWithScores", "hincrByFloat", "hmset", "renamenx", "zrem", "msetnx",
            "hmget", "sunion", "hget", "zadd", "move", "subscribe", "geopos", "mset", "zrangeByScoreWithScores",
            "zscore", "pexpireAt", "georadiusByMember", "ttl", "lrange", "smembers", "pfmerge", "rpush", "publish",
            "mget", "sscan", "append", "sismember"));
    }

    @Override
    protected StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
        return null;
    }
}
